﻿~~~c++
#include <iostream>
#include <string>
#include <stdio.h>
#include <WinSock2.h>
#include <Windows.h>
#include <WS2tcpip.h>  //Windows.h 和 WS2tcpip.h：用于 Windows 套接字编程。
#include <process.h>   // 包含 _beginthreadex 所需的头文件


#pragma comment(lib,"Ws2_32.lib")  //链接 Windows 套接字库。

#define BUF_SIZE  512
char  szMsg[BUF_SIZE];



void SetConsoleColor(WORD color)  //设置控制台文本的颜色。
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hConsole, color);
}


unsigned __stdcall SendMsg(void* arg)
{
	static int i = 1;
	if (i == 1)
	{
		// 设置颜色为蓝色
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_INTENSITY);
		SOCKET sock = *((SOCKET*)arg);
		std::string msg;
		std::getline(std::cin, msg);
		if (msg == "QUIT" || msg == "quit")
		{
			closesocket(sock);
			exit(0);
		}
		send(sock, msg.c_str(), static_cast<int>(msg.length()), 0); // 显式转换为 int 以消除警告,因为win里面的send要求第三参数为int
		// 恢复默认颜色
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
		i++;
	}
	SOCKET sock = *((SOCKET*)arg);
	std::string msg;
	while (1)
	{
		std::getline(std::cin, msg);
		if (msg == "QUIT" || msg == "quit")
		{
			closesocket(sock);
			exit(0);
		}

		send(sock, msg.c_str(), static_cast<int>(msg.length()), 0); // 显式转换为 int 以消除警告
	}
	
	return 0;

}

unsigned __stdcall RecvMsg(void* arg)
{
	SOCKET sock = *((SOCKET*)arg);
	char msg[BUF_SIZE];
    memset(buffer, 0, sizeof(msg)); // 清空接收缓冲区
	while (1)
	{
		int len = recv(sock, msg, sizeof(msg)-1, 0);  //第三个参数-1的原因是为了保留字符数组最后一个空间是'\0'结束符
		if (len == -1)
		{
            perror("rev接受失败！！！");
			return -1;
		}
		// 设置颜色为绿色
		SetConsoleColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);

		printf("%s\n", msg); 
		
		// 恢复默认颜色
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
	}
	return 0;

}

int main()
{
    //一个通用的 Winsock 初始化例程
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	
	wVersionRequested = MAKEWORD(2, 2);
	
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		return -1;
	}
	
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		WSACleanup();
		return -1;
	}

    
	SOCKET hSock;
	hSock = socket(AF_INET, SOCK_STREAM, 0);
	
	SOCKADDR_IN servAdr;
	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family = AF_INET;
	servAdr.sin_port = htons(端口号);
	inet_pton(AF_INET, "远程ip地址", &servAdr.sin_addr);
	
	if (connect(hSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
	{
		printf("connect error: %d", GetLastError());
		return -1;
	}
	else
	{
		// 设置颜色为红色
		SetConsoleColor(FOREGROUND_BLUE | FOREGROUND_INTENSITY);
	
		printf("欢迎来到私人聊天室,请输入你的聊天用户名: ");
	
		// 恢复默认颜色
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);


		HANDLE hSendHand = (HANDLE)_beginthreadex(NULL, 0, SendMsg, (void*)&hSock, 0, NULL);
		HANDLE hRecvHand = (HANDLE)_beginthreadex(NULL, 0, RecvMsg, (void*)&hSock, 0, NULL);
	
		if (hSendHand == NULL || hRecvHand == NULL)
		{
			printf("Thread creation error\n");
			closesocket(hSock);
			WSACleanup();
			return -1;
		}
	
		WaitForSingleObject(hSendHand, INFINITE);
		WaitForSingleObject(hRecvHand, INFINITE);
	
		closesocket(hSock);
		WSACleanup();
		return 0;
	}

}
~~~

